package com.sun.lib;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import androidx.annotation.ColorInt;
import androidx.annotation.StyleableRes;

import com.sun.lib.clip.ClipHelper;
import com.sun.lib.clip.ClipPathManager;
import com.sun.lib.clip.IClip;
import com.sun.lib.shadow.ShadowDrawable;

/**
 * Created by Administrator on 2019/5/7.
 * <p>
 * #                                                   #
 * #                       _oo0oo_                     #
 * #                      o8888888o                    #
 * #                      88" . "88                    #
 * #                      (| -_- |)                    #
 * #                      0\  =  /0                    #
 * #                    ___/`---'\___                  #
 * #                  .' \\|     |# '.                 #
 * #                 / \\|||  :  |||# \                #
 * #                / _||||| -:- |||||- \              #
 * #               |   | \\\  -  #/ |   |              #
 * #               | \_|  ''\---/''  |_/ |             #
 * #               \  .-\__  '-'  ___/-. /             #
 * #             ___'. .'  /--.--\  `. .'___           #
 * #          ."" '<  `.___\_<|>_/___.' >' "".         #
 * #         | | :  `- \`.;`\ _ /`;.`/ - ` : | |       #
 * #         \  \ `_.   \_ __\ /__ _/   .-` /  /       #
 * #     =====`-.____`.___ \_____/___.-`___.-'=====    #
 * #                       `=---='                     #
 * #     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   #
 * #                                                   #
 * #               佛祖保佑         永无BUG              #
 * #                                                   #
 */
public class
SBaseHelper<T extends View> implements ViewTreeObserver.OnGlobalLayoutListener {
    protected int BG_TYPE_COLOR = 1, BG_TYPE_ARRAY = 2, BG_TYPE_IMG = 3;
    private static final int DEFAULT_SHADOW_HEIGHT = 5;

    //corner
    protected float mCornerRadius;
    private float mCornerRadiusTL;
    private float mCornerRadiusTR;
    private float mCornerRadiusBL;
    private float mCornerRadiusBR;

    //BorderWidth
    protected float mBorderWidth = 0;
    private float mBorderDashGap = 0;
    private float mBorderDashWidth = 0;

    private int mBorderWidthUnable = 0;
    private int mBorderWidthChecked = 0;
    private int mBorderWidthSelected = 0;


    //BorderColor
    private int mBorderColor;
    private int mBorderColorUnable;
    private int mBorderColorChecked;
    private int mBorderColorSelected;

    //Background
    private int mBackgroundColor;
    private int mBackgroundColorUnable;
    private int mBackgroundColorChecked;
    private int mBackgroundColorSelected;

    //backgroundColorArray
    private int[] mBackgroundColorArray;
    private int[] mBackgroundColorArrayUnable;
    private int[] mBackgroundColorArrayChecked;
    private int[] mBackgroundColorArraySelected;

    private GradientDrawable mBackground;
    private GradientDrawable mBackgroundUnable;
    private GradientDrawable mBackgroundChecked;
    private GradientDrawable mBackgroundSelected;

    //背景drawable
    private Drawable mBackgroundBmp;
    private Drawable mBackgroundUnableBmp;
    private Drawable mBackgroundCheckedBmp;
    private Drawable mBackgroundSelectedBmp;

    //背景类型
    private int mBgType;
    private int mBgUnableType;
    private int mBgCheckedType;
    private int mBgSelectedType;

    // shadow
    private ShadowDrawable mShadowDrawable;
    private int mShadowDx;
    private int mShadowDy;
    private int mShadowColor;
    private int mShadowRadius;
    private boolean leftShow;
    private boolean rightShow;
    private boolean topShow;
    private boolean bottomShow;


    private boolean mIsEnabled = true;

    private int[][] states = new int[6][];
    private StateListDrawable mStateBackground;
    protected float mBorderRadii[] = new float[8];


    private Context mContext;

    protected T mView;
    private Drawable mViewBackground;
    private Drawable mBackgroundDrawable;

    protected ClipHelper mClipHelper = new ClipHelper();
    //clipLayout 裁剪子组件
    @Deprecated
    private boolean mClipLayout;

    private int mPaddingLeftInital = 0;
    private int mPaddingTopInital = 0;
    private int mPaddingRightInital = 0;
    private int mPaddingBottomInital = 0;


    protected int leftPadding;
    protected int rightPadding;
    protected int topPadding;
    protected int bottomPadding;

    private Paint clipPaint;
    private Paint shadowPaint;


    public SBaseHelper(Context context, T view, AttributeSet attrs) {
        mView = view;
        mContext = context;
        initPaint();
        initPadding();
        //初始化控件属性
        initAttributeSet(context, attrs);
        //监听view大小改变
        addOnGlobalLayoutListener();

        /*setup();

        setBorder();

        setRadiusValue();*/
        setPadding();
    }

    private void initPadding() {
        mPaddingLeftInital = mView.getPaddingLeft();
        mPaddingTopInital = mView.getPaddingTop();
        mPaddingRightInital = mView.getPaddingRight();
        mPaddingBottomInital = mView.getPaddingBottom();
    }

    private void addOnGlobalLayoutListener() {
        if (mView == null) return;
        mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
            @Override
            public void onViewAttachedToWindow(View v) {
                ViewTreeObserver observer = v.getViewTreeObserver();
                observer.addOnGlobalLayoutListener(SBaseHelper.this);
            }

            @Override
            public void onViewDetachedFromWindow(View v) {
                ViewTreeObserver observer = v.getViewTreeObserver();
                observer.removeGlobalOnLayoutListener(SBaseHelper.this);
                v.removeOnAttachStateChangeListener(this);
            }
        });
    }

    /**
     * 初始化控件属性
     *
     * @param context
     * @param attrs
     */
    private void initAttributeSet(Context context, AttributeSet attrs) {
        if (context == null || attrs == null) {
            return;
        }

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SBaseView);
        //圆角
        mCornerRadius = array.getDimensionPixelSize(R.styleable.SBaseView_corner_radius, -1);
        mCornerRadiusBL = array.getDimensionPixelSize(R.styleable.SBaseView_corner_radius_BL, -1);
        mCornerRadiusBR = array.getDimensionPixelSize(R.styleable.SBaseView_corner_radius_BR, -1);
        mCornerRadiusTL = array.getDimensionPixelSize(R.styleable.SBaseView_corner_radius_TL, -1);
        mCornerRadiusTR = array.getDimensionPixelSize(R.styleable.SBaseView_corner_radius_TR, -1);
        //边框
        mBorderColor = array.getColor(R.styleable.SBaseView_border_color, Color.TRANSPARENT);
        mBorderWidth = array.getDimension(R.styleable.SBaseView_border_width, 0);
        mBorderColorUnable = array.getColor(R.styleable.SBaseView_border_color_unable, Color.TRANSPARENT);
        mBorderWidthUnable = array.getDimensionPixelSize(R.styleable.SBaseView_border_with_unable, 0);
        initBorderParams();


        mBorderWidthSelected = array.getDimensionPixelSize(R.styleable.SBaseView_border_with_selected, 0);
        mBorderColorSelected = array.getColor(R.styleable.SBaseView_border_color_selected, Color.TRANSPARENT);
        mBorderColorChecked = array.getColor(R.styleable.SBaseView_border_color_checked, Color.TRANSPARENT);
        //背景
        Object[] bgInfo = getBackgroundInfo(array, R.styleable.SBaseView_background_normal);
        mBgType = (int) bgInfo[0];
        mBackgroundColor = (int) bgInfo[1];
        mBackgroundColorArray = (int[]) bgInfo[2];
        mBackgroundBmp = (Drawable) bgInfo[3];

        Object[] bgInfoUnable = getBackgroundInfo(array, R.styleable.SBaseView_background_unable);
        mBgUnableType = (int) bgInfoUnable[0];
        mBackgroundColorUnable = (int) bgInfoUnable[1];
        mBackgroundColorArrayUnable = (int[]) bgInfoUnable[2];
        mBackgroundUnableBmp = (Drawable) bgInfoUnable[3];

        Object[] bgInfoSelected = getBackgroundInfo(array, R.styleable.SBaseView_background_selected);
        mBgSelectedType = (int) bgInfoSelected[0];
        mBackgroundColorSelected = (int) bgInfoSelected[1];
        mBackgroundColorArraySelected = (int[]) bgInfoSelected[2];
        mBackgroundSelectedBmp = (Drawable) bgInfoSelected[3];

        Object[] bgInfoChecked = getBackgroundInfo(array, R.styleable.SBaseView_background_checked);
        mBgCheckedType = (int) bgInfoChecked[0];
        mBackgroundColorChecked = (int) bgInfoChecked[1];
        mBackgroundColorArrayChecked = (int[]) bgInfoChecked[2];
        mBackgroundCheckedBmp = (Drawable) bgInfoChecked[3];
        // 阴影
        mShadowColor = array.getColor(R.styleable.SBaseView_shadow_color, Color.TRANSPARENT);
        mShadowRadius = array.getDimensionPixelSize(R.styleable.SBaseView_shadow_radius, 0);

        mShadowDx = array.getDimensionPixelSize(R.styleable.SBaseView_shadow_offset_X, 0);
        mShadowDy = array.getDimensionPixelSize(R.styleable.SBaseView_shadow_offset_Y, 0);
        leftShow = !array.getBoolean(R.styleable.SBaseView_shadow_hidden_left, false);
        rightShow = !array.getBoolean(R.styleable.SBaseView_shadow_hidden_right, false);
        topShow = !array.getBoolean(R.styleable.SBaseView_shadow_hidden_top, false);
        bottomShow = !array.getBoolean(R.styleable.SBaseView_shadow_hidden_bottom, false);
        mClipLayout = array.getBoolean(R.styleable.SBaseView_clip_layout, false);
        array.recycle();
    }

    private void initBorderParams() {
        /*if (mBorderWidth > 0 && mBorderColor != Color.TRANSPARENT) {
            if (mBorderWidthSelected == 0) {
                mBorderWidthSelected = (int) mBorderWidth;
            }
        }*/
    }

    private void setup() {
        boolean isEnabled = mView.isEnabled();
        if (isEnabled)
            mView.setEnabled(mIsEnabled);
        mBackground = new GradientDrawable();
        mBackgroundUnable = new GradientDrawable();
        mBackgroundChecked = new GradientDrawable();
        mBackgroundSelected = new GradientDrawable();


        if (useShadow()) mShadowDrawable = new ShadowDrawable();
        mViewBackground = mView.getBackground();

        /*if (mViewBackground != null && mViewBackground instanceof StateListDrawable) {
            mStateBackground = (StateListDrawable) mViewBackground;
        } else {
            mStateBackground = new StateListDrawable();
        }*/
        mStateBackground = new StateListDrawable();

        //设置默认值

        if (mBackgroundColor == 0 && mViewBackground != null && mViewBackground instanceof ColorDrawable) {
            mBackgroundColor = ((ColorDrawable) mViewBackground).getColor();
        }

        if (mBackgroundColorUnable == 0 && mBackgroundColorArrayUnable == null) {
            mBackgroundColorUnable = mBackgroundColor;
            mBackgroundColorArrayUnable = mBackgroundColorArray;
        }

        if (mBackgroundUnableBmp == null) {
            mBackgroundUnableBmp = mBackgroundBmp;
        }


        if (mBackgroundColorChecked == 0 && mBackgroundColorArrayChecked == null) {
            mBackgroundColorChecked = mBackgroundColor;
            mBackgroundColorArrayChecked = mBackgroundColorArray;
        }

        if (mBackgroundCheckedBmp == null) {
            mBackgroundCheckedBmp = mBackgroundBmp;
        }


        if (mBackgroundColorSelected == 0 && mBackgroundColorArraySelected == null) {
            mBackgroundColorSelected = mBackgroundColor;
            mBackgroundColorArraySelected = mBackgroundColorArray;
        }

        if (mBackgroundSelectedBmp == null) {
            mBackgroundSelectedBmp = mBackgroundBmp;
        }

        //设置背景色
        if (mBackgroundColorArray != null && mBackgroundColorArray.length > 0) {
            mBackground = setColors(mBackground, mBackgroundColorArray);
        } else {
            mBackground.setColor(mBackgroundColor);
        }

        if (mBackgroundColorArrayUnable != null && mBackgroundColorArrayUnable.length > 0) {
            mBackgroundUnable = setColors(mBackgroundUnable, mBackgroundColorArrayUnable);
        } else {
            mBackgroundUnable.setColor(mBackgroundColorUnable);
        }
        if (mBackgroundColorArrayChecked != null && mBackgroundColorArrayChecked.length > 0) {
            mBackgroundChecked = setColors(mBackgroundChecked, mBackgroundColorArrayChecked);
        } else {
            mBackgroundChecked.setColor(mBackgroundColorChecked);
        }

        if (mBackgroundColorArraySelected != null && mBackgroundColorArraySelected.length > 0) {
            mBackgroundSelected = setColors(mBackgroundSelected, mBackgroundColorArraySelected);
        } else {
            mBackgroundSelected.setColor(mBackgroundColorSelected);
        }

        states[0] = new int[]{-android.R.attr.state_enabled};
        states[1] = new int[]{android.R.attr.state_enabled, android.R.attr.state_selected};
        states[2] = new int[]{android.R.attr.state_enabled, android.R.attr.state_checked};
        //states[3] = new int[]{android.R.attr.state_enabled,android.R.attr.state_pressed};
        states[3] = new int[]{android.R.attr.state_enabled};
        //此处addState的顺序很重要，和xml中selector一样
        mStateBackground.addState(states[0], mBackgroundUnableBmp == null ? mBackgroundUnable : mBackgroundUnableBmp);
        mStateBackground.addState(states[1], mBackgroundSelectedBmp == null ? mBackgroundSelected : mBackgroundSelectedBmp);
        mStateBackground.addState(states[2], mBackgroundCheckedBmp == null ? mBackgroundChecked : mBackgroundCheckedBmp);
        /*Drawable pressedDrawable;
        if(mView.isSelected()) {
            pressedDrawable = mBackgroundSelectedBmp == null ? mBackgroundSelected : mBackgroundSelectedBmp;
        }else{
            pressedDrawable = mBackgroundBmp == null ? mBackground : mBackgroundBmp;
        }*/
        //mStateBackground.addState(states[3],pressedDrawable);
        mStateBackground.addState(states[3], mBackgroundBmp == null ? mBackground : mBackgroundBmp);

        // setBackgroundState();
    }

    private void setBorder() {
        mBackground.setStroke((int) mBorderWidth, mBorderColor, mBorderDashWidth, mBorderDashGap);
        mBackgroundUnable.setStroke(mBorderWidthUnable, mBorderColorUnable, mBorderDashWidth, mBorderDashGap);
        mBackgroundSelected.setStroke(mBorderWidthSelected, mBorderColorSelected, mBorderDashWidth, mBorderDashGap);
        mBackgroundChecked.setStroke(mBorderWidthChecked, mBorderColorChecked, mBorderDashWidth, mBorderDashGap);
        //   setBackgroundState();
    }

    private GradientDrawable setColors(GradientDrawable drawable, int[] colors) {
        return null;
    }

    /**
     * 设置背景
     */
    private void setBackgroundState() {
        boolean unHasBgColor = mBackgroundColor == 0 && mBackgroundColor == mBackgroundColorSelected && mBackgroundColor == mBackgroundColorUnable;//mBackgroundColor == 0;
        boolean unHasBgColorArray = mBackgroundColorArray == null;
        boolean unHasBgDrawable = mBackgroundBmp == null;

        boolean hasCustomBg = !(unHasBgColor && unHasBgColorArray && unHasBgDrawable);
        /*Drawable drawable = mView.getBackground();
        if (!hasCustomBg && drawable instanceof ColorDrawable) {
            int color = ((ColorDrawable) drawable).getColor();
            setStateBackgroundColor(color, color, color);
        }*/

        if (!hasCustomBg && mViewBackground != null && mViewBackground instanceof ColorDrawable) {
            int color = ((ColorDrawable) mViewBackground).getColor();
            setStateBackgroundColor(color, color, color);
        }
        mBackgroundDrawable = mStateBackground;

        // setShadow();

        setBackGroundCompat(mView.getWidth(), mView.getHeight());

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            // mView.setBackgroundDrawable(hasCustom ? mStateBackground : drawable);
            mView.setBackgroundDrawable(mBackgroundDrawable);
        } else {
            // mView.setBackground(hasCustom ? mStateBackground : drawable);
            mView.setBackground(mBackgroundDrawable);
        }

    }

    private int layerType = 0;

    // 设置阴影
    private void setShadow() {
        if (useShadow()) {
            layerType = mView.getLayerType();
            if (mView.getLayerType() != View.LAYER_TYPE_SOFTWARE)
                mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);  // 禁止硬件加速
            if (mShadowDrawable == null) mShadowDrawable = new ShadowDrawable();
           /* float[] radii = new float[mBorderRadii.length];
            float size = mBorderWidth * 0.5f;
            for (int i = 0; i < radii.length; i++)
                radii[i] = mBorderRadii[i] + size;*/
            mShadowDrawable.updateParameter(mShadowColor, mShadowRadius, mShadowDx, mShadowDy, copyRaii(mBorderRadii, mBorderWidth * 0.5f), leftShow, rightShow, topShow, bottomShow);
            //   mShadowDrawable.setStroke((int) mBorderWidth, mBorderColor, mBorderDashWidth, mBorderDashGap);
            int xPadding = (int) (mShadowDrawable.getShadowOffset() + Math.abs(mShadowDx));
            int yPadding = (int) (mShadowDrawable.getShadowOffset() + Math.abs(mShadowDy));

            int left = leftShow ? xPadding : 0; //mShadowLeftHeight; //
            int top = topShow ? yPadding : 0; //mShadowTopHeight; //
            int right = rightShow ? xPadding : 0;//mShadowRightHeight; //
            int bottom = bottomShow ? yPadding : 0;//mShadowBottomHeight; //

            LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{mShadowDrawable, mBackgroundDrawable});
            // layerDrawable.setBounds(mView.getLeft(),mView.getTop(),mView.getRight(),mView.getBottom());
            //layerDrawable.setBounds(0,0,mView.getWidth(),216);
            layerDrawable.setLayerInset(1, left, top, right, bottom);
            mBackgroundDrawable = layerDrawable;
        }
        setPadding();
    }

    protected void setPadding() {
        if (useShadow()) {
            int xPadding = (int) (mShadowRadius + Math.abs(mShadowDx));
            int yPadding = (int) (mShadowRadius + Math.abs(mShadowDy));

            leftPadding = (int) (leftShow ? xPadding + mPaddingLeftInital + mBorderWidth : mPaddingLeftInital + mBorderWidth);
            rightPadding = (int) (rightShow ? xPadding + mPaddingRightInital + mBorderWidth : mPaddingRightInital + mBorderWidth);
            topPadding = (int) (topShow ? yPadding + mPaddingTopInital + mBorderWidth : mPaddingTopInital + mBorderWidth);
            bottomPadding = (int) (bottomShow ? yPadding + mPaddingBottomInital + mBorderWidth : mPaddingBottomInital + mBorderWidth);
            //  calculateRectF();
        } else {
            leftPadding = (int) (mPaddingLeftInital + mBorderWidth);
            rightPadding = (int) (mPaddingRightInital + mBorderWidth);
            topPadding = (int) (mPaddingTopInital + mBorderWidth);
            bottomPadding = (int) (mPaddingBottomInital + mBorderWidth);
        }
        mView.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
        //Log.d("TAG", "paddingleft:" + mView.getPaddingLeft());
    }

    private boolean useShadow() {
        return mShadowRadius > 0;
    }

    private SBaseHelper setStateBackgroundColor(@ColorInt int color, @ColorInt int unable, @ColorInt int select) {
        mBackgroundColor = color;
        mBackgroundColorUnable = unable;
        mBackgroundColorSelected = select;
        mBackground.setColor(mBackgroundColor);
        mBackgroundUnable.setColor(unable);
        mBackgroundSelected.setColor(select);
        //    setBackgroundState();
        return this;
    }


    private Object[] getBackgroundInfo(TypedArray a, @StyleableRes int styleableRes) {
        int bgType = BG_TYPE_COLOR;
        int bgColor = 0;
        int[] bgColorArray = null;  //多个颜色
        Drawable drawable = null;   //图片资源

        int resId = a.getResourceId(styleableRes, 0);
        if (resId == 0) {
            bgColor = a.getColor(styleableRes, 0);
            bgType = BG_TYPE_COLOR;
        } else {
            String typeName = mContext.getResources().getResourceTypeName(resId);
            if ("array".equals(typeName)) {
                bgType = BG_TYPE_ARRAY;
                String[] strArray = mContext.getResources().getStringArray(resId);
                int[] intArray = mContext.getResources().getIntArray(resId);
                int length = Math.min(intArray.length, strArray.length);
                bgColorArray = new int[length];
                String strIndex;
                int intIndex;
                for (int i = 0; i < length; i++) {
                    strIndex = strArray[i];
                    intIndex = intArray[i];
                    bgColorArray[i] = !TextUtils.isEmpty(strIndex) ? Color.parseColor(strIndex) : intIndex;
                }
            } else if ("color".equals(typeName)) {
                bgColor = a.getColor(styleableRes, 0);
                bgType = BG_TYPE_COLOR;
            } else if ("mipmap".equals(typeName) || "drawable".equals(typeName)) {
                bgType = BG_TYPE_IMG;
                drawable = a.getDrawable(styleableRes);
            }
        }
        return new Object[]{bgType, bgColor, bgColorArray, drawable};
    }

    private void setRadiusValue() {
        float size = 0f;
        if (mCornerRadius > 0) {
            for (int i = 0; i < mBorderRadii.length; i++) {
                mBorderRadii[i] = mCornerRadius + size;
            }
        } else {
            for (int i = 0; i < mBorderRadii.length; i++) {
                mBorderRadii[i] = 0;
            }
            if (mCornerRadiusTL > 0) {
                mBorderRadii[0] = mCornerRadiusTL + size;
                mBorderRadii[1] = mCornerRadiusTL + size;
            }
            if (mCornerRadiusTR > 0) {
                mBorderRadii[2] = mCornerRadiusTR + size;
                mBorderRadii[3] = mCornerRadiusTR + size;
            }
            if (mCornerRadiusBR > 0) {
                mBorderRadii[4] = mCornerRadiusBR + size;
                mBorderRadii[5] = mCornerRadiusBR + size;
            }
            if (mCornerRadiusBL > 0) {
                mBorderRadii[6] = mCornerRadiusBL + size;
                mBorderRadii[7] = mCornerRadiusBL + size;
            }
        }
        setRadiusUI();
    }

    private void setRadiusUI() {
        mBackground.setCornerRadii(mBorderRadii);
        mBackgroundUnable.setCornerRadii(mBorderRadii);
        mBackgroundChecked.setCornerRadii(mBorderRadii);
        mBackgroundSelected.setCornerRadii(mBorderRadii);
        setBackgroundState();
    }

    private void setBackGroundCompat(int w, int h) {
        if (useShadow() && w > 0 && h > 0) {
            Bitmap bitmap = createShadowBitmap(w, h, mShadowDx, mShadowDy, mShadowRadius, Color.TRANSPARENT);
            BitmapDrawable shadowDrawable = new BitmapDrawable(bitmap);

            int xPadding = (int) (mShadowRadius + Math.abs(mShadowDx));
            int yPadding = (int) (mShadowRadius + Math.abs(mShadowDy));

            int left = leftShow ? xPadding : 0; //leftShow?mShadowRadius-mShadowDx:0;//  //mShadowLeftHeight; //
            int top = topShow ? yPadding : 0;//topShow?mShadowRadius-mShadowDy:0;//  //mShadowTopHeight; //
            int right = rightShow ? xPadding : 0;//rightShow?mShadowRadius+mShadowDx:0;////mShadowRightHeight; //
            int bottom = bottomShow ? yPadding : 0;//bottomShow?mShadowRadius+mShadowDy:0; ////mShadowBottomHeight; //

            LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{shadowDrawable, mBackgroundDrawable});
            layerDrawable.setLayerInset(1, left, top, right, bottom);
            mBackgroundDrawable = layerDrawable;
        }
        //  setPadding();
    }

    private Bitmap createShadowBitmap(int w, int h, int dx, int dy, int shadowRadius, int fillColor) {
        h += 2 * shadowRadius;
        w += 2 * shadowRadius;

        dx = (int) (dx / 2f);
        dy = (int) (dy / 2f);
        w = w / 2 == 0 ? 1 : w / 2;
        h = h / 2 == 0 ? 1 : h / 2;
        float cornerRadius = mCornerRadius / 2;
        shadowRadius = (int) (shadowRadius / 2f);

        Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(output);
        float rect_left, rect_right, rect_top, rect_bottom;
        int xPadding = Math.abs(dx);
        int yPadding = Math.abs(dy);

        rect_left = leftShow ? shadowRadius : 0;
        rect_right = w - (rightShow ? shadowRadius : 0);
        rect_top = topShow ? shadowRadius : 0;
        rect_bottom = h - (bottomShow ? shadowRadius : 0);

        RectF shadowRect = new RectF(rect_left, rect_top, rect_right, rect_bottom);

        shadowRect.top += yPadding;
        shadowRect.bottom -= yPadding;
        shadowRect.left += xPadding;
        shadowRect.right -= xPadding;

        shadowPaint.setColor(fillColor);
        if (!mView.isInEditMode()) {
            shadowPaint.setShadowLayer(shadowRadius * 0.7f, dx, dy, mShadowColor);
        }
        if (mCornerRadius > 0) {
            canvas.drawRoundRect(shadowRect, cornerRadius, cornerRadius, shadowPaint);
        } else {
            //   float[] raii = copyRaii(mBorderRadii, mBorderWidth * 0.5f);

            int topLeft = (int) (mCornerRadiusTL / 2);
            int topRight = (int) (mCornerRadiusTR / 2);
            int bottomLeft = (int) (mCornerRadiusBL / 2);
            int bottomRight = (int) (mCornerRadiusBR / 2);

            float[] raii = new float[]{topLeft, topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft};

            Path path = new Path();
            path.addRoundRect(shadowRect, raii, Path.Direction.CW);
            canvas.drawPath(path, shadowPaint);
        }

        return output;
    }

    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (w > 0 && h > 0) {
            setup();

            setBorder();

            setRadiusValue();
        }
    }

    public void onDraw(Canvas canvas) {

    }

    /**
     * 设置圆角
     *
     * @param topLeft
     * @param topRight
     * @param bottomLeft
     * @param bottomRight
     * @return
     */
    public SBaseHelper setCornerRadius(float topLeft, float topRight, float bottomLeft, float bottomRight) {
        this.mCornerRadius = -1;
        this.mCornerRadiusTL = topLeft;
        this.mCornerRadiusTR = topRight;
        this.mCornerRadiusBL = bottomLeft;
        this.mCornerRadiusBR = bottomRight;
        setRadiusValue();
        return this;
    }

    /**
     * 设置圆角
     *
     * @param radius
     */
    public void setmCornerRadius(float radius) {
        this.mCornerRadius = radius;
        setRadiusValue();
    }

    private int dp2px(Context context, float dp) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    private void initPaint() {
        clipPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        clipPaint.setColor(Color.WHITE);
        clipPaint.setStyle(Paint.Style.FILL);

        shadowPaint = new Paint();
        shadowPaint.setAntiAlias(true);
        shadowPaint.setStyle(Paint.Style.FILL);
    }

    private void initClip() {
        /*mClipHelper.initClip(mView, mClipLayout, mShadowDrawable, mBorderRadii, (width, height) -> {
            Path path = new Path();
            if (mShadowDrawable != null) {
                path.addRoundRect(new RectF(mShadowDrawable.getRectF()), mBorderRadii, Path.Direction.CCW);
            } else {
                path.addRoundRect(new RectF(0, 0, width, height), mBorderRadii, Path.Direction.CCW);
            }
            return path;
        });*/
    }

    protected float[] copyRaii(float[] radii, float offset) {
        if (radii == null) return null;
        float[] values = new float[radii.length];
        for (int i = 0; i < values.length; i++)
            values[i] = radii[i] + offset;
        return values;
    }


    /*public void dispatchDrawBefore(Canvas canvas) {
        int outHeight = (int) (rectf.bottom - rectf.top);
        if (mView instanceof ViewGroup && ((ViewGroup) mView).getChildAt(0) != null) {
            Path path = new Path();
            if (mCornerRadius > outHeight * 0.5f) {
                path.addRoundRect(rectf, outHeight / 2, outHeight / 2, Path.Direction.CW);
            } else {
                path.addRoundRect(rectf, copyRaii(mBorderRadii, -mBorderWidth * 0.5f), Path.Direction.CCW);
            }
            // 1. 通过裁剪方式
            canvas.clipPath(path);
        }
    }*/

    /*public void dispatchDrawAfter(Canvas canvas) {
        // mClipHelper.dispatchDraw(canvas);
    }*/


    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
        mClipHelper.onLayout(changed, left, top, right, bottom);
    }

    @Override
    public void onGlobalLayout() {
       /* ViewTreeObserver observer = mView.getViewTreeObserver();
        observer.removeOnGlobalLayoutListener(SBaseHelper.this);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            float half = mView.getHeight() / 2f;
            for (int i = 0; i < mBorderRadii.length; i++) {
                if (mBorderRadii[i] > half) mBorderRadii[i] = half;
            }
        }*/
        // 渐变

        initClip();
        //  setShadow();
    }
}
